require 'sketchup.rb'
require 'extensions.rb'

module ChallengeCup

    # 清空console
def self.console_clear


	unless SKETCHUP_CONSOLE.visible?
	  # Sketchup.send_action("showRubyPanel:")
	  SKETCHUP_CONSOLE.show
	end
    SKETCHUP_CONSOLE.clear



end

def self.wsn_make_menu
    
    add_separator_to_menu("Plugins")
    cupmenu = UI.menu("Plugins").add_submenu("挑战杯2025")
    cup_cmd = UI::Command.new("cup") { output_triangles}
    cup_cmd.menu_text = "输出三角形s"
    cupmenu.add_item cup_cmd
    add_separator_to_menu("Plugins")
end

def self.wsn_make_toolbar
    toolbar = UI::Toolbar.new "挑战杯2025"
    cup_cmd = UI::Command.new("cup") {output_triangles}
    cup_cmd.small_icon = "cup_large_icon.png"
    cup_cmd.large_icon = "cup_large_icon.png"
    cup_cmd.tooltip = "输出三角形s"
    cup_cmd.status_bar_text = "输出三角形s"
    cup_cmd.menu_text = "输出三角形s"
    toolbar = toolbar.add_item cup_cmd

    cup_clear_cmd = UI::Command.new("clear") {console_clear}
    cup_clear_cmd.small_icon = "clear_large_icon.png"
    cup_clear_cmd.large_icon = "clear_large_icon.png"
    cup_clear_cmd.tooltip = "清空"
    cup_clear_cmd.status_bar_text = "清空"
    cup_clear_cmd.menu_text = "清空"
    toolbar = toolbar.add_item cup_clear_cmd

    toolbar.show
end


#用该方法就可以遍历模型中的所有的faces。在其中调用面的写入文件方法。
# 注意 该方法调用的 sunshine_polygon_2_triangles 使用了一个全局变量 $output_file。
def self.wsn_find_faces(others, entities, tform, layername, head_string, material)

    entities.each do |entity|

        if( entity.typename == "Face")
            #Face entity
            #UI.messagebox entity.typename + "tttt"
            # 把面写入file文件

            #面累计加1
            $wsn_face_count = $wsn_face_count + 1
            #在这里调用面的写入文件方法。
			#在sketchup的高版本中，polygon_2_triangles好像已经被内置的函数定义了一次所以要加上sunshine
            sunshine_polygon_2_triangles(entity, tform, head_string, material)

            #Group entity
        elsif( entity.typename == "Group")
        	
            

            if entity.name==""
                entity.name="GROUP"+$group_count.to_s
                $group_count = $group_count + 1
            end

            groupMaterial = entity.material

            others = wsn_find_faces(others, entity.entities, tform * entity.transformation, entity.name,head_string, groupMaterial)
			
			
            #Componentinstance entity
        elsif( entity.typename == "ComponentInstance")
            if entity.name==""
                entity.name="COMPONENT"+$component_count.to_s
                $component_count = $component_count + 1
            end
            componentMaterial = entity.material

            others = wsn_find_faces(others, entity.definition.entities, tform * entity.transformation, entity.name,head_string, componentMaterial)
        else
            others = others + 1
        end
    end
    others
end # def self.wsn_find_faces(others, entities, tform, layername, head_string)

#把一个凹多边形，分解为若干个三角形，并打印出他们的各个面的点的值，注意高版本的"SketchUp"中polygon_2_triangles（）函数已经被定义过了。
def self.sunshine_polygon_2_triangles (my_face, tform ,head_string, groupComponentMaterial)

	#一行是一个mesh mesh的开头是
	total_string = ""
	
    if(my_face.typename!="Face")
        # puts "miss one from sunshine_polygon_2_triangles"
        return
    end
	

	
    # 把face的material搞出来。2025年7月8日
    # 有可能face的matertial是空的，所以，预先给个值
    red = 255
    green = 255
    blue = 255
    alpha = 255
    
    material = my_face.material
    # puts "material = "
    # puts material
    # 有可能face的matertial是空的，所以，预先给个值
    if material != nil
        color = material.color

        red = color.red
        green = color.green
        blue = color.blue
        alpha = color.alpha
    elsif groupComponentMaterial!= nil
        color = groupComponentMaterial.color

        red = color.red
        green = color.green
        blue = color.blue
        alpha = color.alpha
    end
	
	# 下面有两个套路，如果face里面有空洞，就用老办法。
	loops = my_face.loops
	outer_loop = my_face.outer_loop
	
	# puts " --- --- --- "
	# if outer_loop.convex?
	#   puts "outer Loop is convex. length ="
	# else
	#   puts "outer Loop is not convex. length ="
	# end
	# puts outer_loop.vertices
	# puts " --- --- --- "
	# puts my_face.loops.count
	# puts my_face.edges.any? { |edge| edge.soft? || edge.smooth? }
	# puts my_face.edges.count
	# puts " --- --- --- "
	# puts my_face.edges.length
	# puts my_face.vertices.count
	# puts my_face.outer_loop.vertices.count
	# puts my_face.vertices.count != my_face.outer_loop.vertices.count
	
	# puts my_face.outer_loop.vertices.length
	# puts " --- --- --- "
	
	# # outer_area = my_face.outer_loop.area
	# # actual_area = my_face.area
	# # puts !outer_area.approximate?(actual_area)
    # puts " --- --- --- "
  
  	
	
	# 如果loop是0个，跳出
	if loops.length == 0
		return
	end
	# 判断loop里面有没有洞。如果loop是一个，内部没有洞
	test_face_mesh_polygons_count = my_face.mesh.polygons.count
	# puts test_face_mesh_polygons_count
	# puts outer_loop.vertices.count
	# if loops.length <= 1 and my_face.vertices.count < 5 
	if test_face_mesh_polygons_count + 2 == outer_loop.vertices.count
		total_array_string = ""
		
		triangle_string = "[" 
	
		outer_loop.vertices.each do |vertex|
			
			
			position3d = vertex.position
			position3d.transform! tform
			triangle_string = triangle_string +
				position3d.x.to_mm.round(4).to_s + "," + 
				position3d.y.to_mm.round(4).to_s + "," +
				position3d.z.to_mm.round(4).to_s + ","
		end
		
		# 还要加上颜色
		triangle_string = triangle_string + red.to_s + "," + green.to_s + "," + blue.to_s + "," + alpha.to_s +  "]," 
		total_array_string = total_array_string + triangle_string
		
		#entities.erase_entities my_face
		$output_file = $output_file + total_array_string
	
	else # if loops.length > 1 # 判断loop里面有没有洞。如果loop大于1，内部有洞用老算法。
	
		##########################下面这些东西做的都不太好。应该不用两次my_face.reverse!可能影响速度
		my_mesh = nil
		
		# 测算这个三角形是不是reversed
		x = tform.xaxis
		y = tform.yaxis
		z = tform.zaxis
		#如果x，y，z中有偶数为负，ok，如果有奇数为负，三角形要换方向
		if(x.x * y.y * z.z < 0)
			my_face.reverse!
			my_mesh = my_face.mesh 0
			my_face.reverse!
		else
			my_mesh = my_face.mesh 0
		end
		#puts "x.x= " + x.x.to_s + " x.y= " + x.y.to_s + " x.z= " + x.z.to_s
		#puts "y.x= " + y.x.to_s + " y.y= " + y.y.to_s + " y.z= " + y.z.to_s
		#puts "z.x= " + z.x.to_s + " z.y= " + z.y.to_s + " z.z= " + z.z.to_s
		##########################上面这些东西做的都不太好。应该不用两次my_face.reverse!可能影响速度
		
		total_array_string = ""
		#TODO 这个暂时先不做
		my_mesh.transform! tform
		polygons = my_mesh.polygons
		polygons.each do |polygon|
			if (polygon.length > 2)
				
				triangle_string = "[" 

				for j in 0...polygon.length do
					
					#如果是xml方式，写入 	<point x="0.00" y="0.1" z="0.2"></point>
			
					triangle_string = triangle_string + 
				(my_mesh.point_at(polygon[j].abs).x.to_mm ).round(4).to_s + "," + 
				(my_mesh.point_at(polygon[j].abs).y.to_mm ).round(4).to_s + "," +
				(my_mesh.point_at(polygon[j].abs).z.to_mm ).round(4).to_s + ","
									

						#total_string = total_string + " " + (my_mesh.point_at(polygon[j].abs).x.to_f ).to_s + " " + (my_mesh.point_at(polygon[j].abs).y.to_f ).to_s + " " + (my_mesh.point_at(polygon[j].abs).z.to_f ).to_s			
				end
				# 还要加上颜色
				triangle_string = triangle_string + red.to_s + "," + green.to_s + "," + blue.to_s + "," + alpha.to_s +  "]," 
				total_array_string = total_array_string + triangle_string

				$wsn_trangle_count = $wsn_trangle_count + 1
			end

		end
		#entities.erase_entities my_face
		$output_file = $output_file + total_array_string
	
	end # 判断loop里面有没有洞。
	
end

def self.output_triangles 

	unless SKETCHUP_CONSOLE.visible?
	  # Sketchup.send_action("showRubyPanel:")
	  SKETCHUP_CONSOLE.show
	end

    # 最后输出到窗口的
	$output_file = "["
	$wsn_face_count = 0
    $wsn_trangle_count = 0
	$group_count = 0
	$component_count = 0

    model = Sketchup.active_model

    # puts model.materials
    # model.materials.each do |mat|
    #     puts mat.to_s
    # end

	#先输出选择的面
	ss = model.selection
    if (ss.length > 0)
        others = wsn_find_faces(0, ss, Geom::Transformation.new(), model.active_layer.name, "SFACE", nil)
    end	
	
    puts $output_file[0...-1] + "]"

    
    UI.messagebox("面数： " + $wsn_face_count.to_s + "\n三角形数： " + $wsn_trangle_count.to_s)


end

unless file_loaded?(__FILE__)
    wsn_make_toolbar   
    wsn_make_menu
end

end # module Qsunshine